package com.sbj.service.impl;

import cn.dev33.satoken.stp.StpUtil;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.zhxu.bs.BeanSearcher;
import cn.zhxu.bs.operator.Contain;
import cn.zhxu.bs.operator.Equal;
import cn.zhxu.bs.util.MapUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sbj.config.OrderGenerate;
import com.sbj.dto.req.OrderGoodsReq;
import com.sbj.dto.req.OrderReq;
import com.sbj.dto.req.ShopOrderReq;
import com.sbj.dto.req.SubmitOrderReq;
import com.sbj.dto.res.OrderGoodsRes;
import com.sbj.dto.res.OrderItemRes;
import com.sbj.dto.res.OrderRes;
import com.sbj.dto.res.ShopOrderRes;
import com.sbj.dto.utils.Search;
import com.sbj.entity.*;
import com.sbj.mapper.OrderMapper;
import com.sbj.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zmh.framework.constants.Constants;
import com.zmh.framework.exception.ResultException;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author summer
 * @since 2024/08/10 10:02:39
 */
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    private final BeanSearcher beanSearcher;

    @Override
    public Page<ShopOrderRes> lists(OrderReq orderReq) {
        Page<ShopOrderRes> page=new Page<>(orderReq.getPageNum(),orderReq.getPageSize());
        return this.baseMapper.findOrderLists(page,orderReq);
    }

    private final GoodsService goodsService;

    private final OrderGoodsService orderGoodsService;

    private final CarService carService;

    private final OrderGenerate orderGenerate;

    private final IExpendService expendService;

    @Override
    public void submitOrder(SubmitOrderReq req) {
        Order convert = new Order();
        convert.setMemberId(StpUtil.getLoginIdAsInt());
        convert.setOrderNo(orderGenerate.createNo());
        convert.setAddressId(req.getAddressId());
        convert.setOrderState(req.getOrderState());
        this.save(convert);
        List<OrderGoods> orderGoodsList= ListUtil.list(true);
        BigDecimal orderPrice=BigDecimal.ZERO;
        List<Goods> goodsList=ListUtil.list(true);
        for (OrderGoodsReq orderGood: req.getOrderGoods()){
            Goods goods = goodsService.getById(orderGood.getGoodsId());
            if(ObjectUtil.isNull(goods)){
                throw new ResultException(goods.getName()+":商品不存在，请联系运营人员");
            }
            if(goods.getStock()<= Constants.ZERO || orderGood.getGoodsNum()>goods.getStock()){
                throw new ResultException(goods.getName()+":商品库存不足，请联系运营人员");
            }
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setOrderId(convert.getId());
            orderGoods.setGoodsId(orderGood.getGoodsId());
            orderGoods.setGoodsNum(orderGood.getGoodsNum());
            orderGoods.setGoodsPrice(goods.getRuingPrice());
            orderGoodsList.add(orderGoods);
            goods.setStock(goods.getStock() - orderGood.getGoodsNum());
            goodsList.add(goods);
            if(req.getOrderState().equals(Constants.ONE)){
                Integer carId = orderGood.getCarId();
                carService.removeById(carId);
            }
            orderPrice = orderPrice.add(orderGood.getGoodsPrice());
        }

        orderGoodsService.saveBatch(orderGoodsList);
        goodsService.updateBatchById(goodsList);
        if (req.getOrderState().equals(Constants.ONE)){
            convert.setPayTime(LocalDateTime.now());
            updateMemberCoupons(orderPrice);
        }
        convert.setGoodsPrice(orderPrice);
        this.updateById(convert);
    }

    private final IMemberService memberService;

    private void updateMemberCoupons(BigDecimal orderPrice){
        Expend expend=new Expend();
        expend.setType(Constants.ONE);
        expend.setName("购买商品");
        expend.setPrice(orderPrice);
        expend.setMemberId(StpUtil.getLoginIdAsInt());
        expend.setSerialNum("C"+ RandomUtil.randomNumbers(12));
        expendService.save(expend);
        Member member = memberService.getById(StpUtil.getLoginIdAsInt());
        /**
         * 抵扣优惠券
         */
        BigDecimal coupons = member.getCoupons();
        if(orderPrice.compareTo(coupons)>0){
            throw new ResultException("优惠券金额不足不能购买当前商品");
        }
        //更新优惠券
        member.setCoupons(NumberUtil.sub(coupons, orderPrice));
        memberService.updateById(member);
    }

    @Override
    public Page<ShopOrderRes> shopOrderLists(ShopOrderReq req) {
        req.setMemberId(StpUtil.getLoginIdAsInt());
        Page<ShopOrderRes> page=new Page<>(req.getPageNum(),req.getPageSize());
        page = this.baseMapper.shopOrderLists(page, req);
        return page;
    }

    @Override
    public void resubmitOrder(OrderReq req) {
        Order order = this.getById(req.getId());
        if(ObjectUtil.isNull(order)){
            throw new ResultException("订单不存在");
        }
        order.setOrderState(Constants.TWO);
        order.setPayTime(LocalDateTime.now());
        this.updateById(order);
        updateMemberCoupons(order.getGoodsPrice());
    }

    @Override
    public void updateShopOrder(ShopOrderReq req) {
        Order order = this.getById(req.getOrderId());
        if(ObjectUtil.isNull(order)){
            throw new ResultException("订单不存在");
        }
        order.setOrderState(req.getOrderStatus());
        this.updateById(order);
    }

    @Override
    public List<OrderGoodsRes> getOrderGoodsById(Integer orderId) {
        Map<String, Object> build = MapUtils.builder().field(OrderGoodsRes::getOrderId, orderId).op(Equal.class).build();
        return beanSearcher.searchList(OrderGoodsRes.class,build);
    }

    @Override
    public OrderItemRes findOrderItem(Integer orderId) {
        return this.baseMapper.findOrderItem(orderId);
    }

    private final OrderKdService orderKdService;

    @Override
    public void orderDeliver(OrderReq orderReq) {
        ShopOrderReq shopOrderReq = new ShopOrderReq();
        shopOrderReq.setOrderStatus(Constants.TWO);
        shopOrderReq.setOrderId(orderReq.getId());
        updateShopOrder(shopOrderReq);
        OrderKd orderKd=new OrderKd();
        orderKd.setOrderId(orderReq.getId());
        orderKd.setKdId(orderReq.getKdId());
        orderKd.setKdCode(orderReq.getKdCode());
        orderKdService.save(orderKd);
    }
}
